#include <stdlib.h>
#include "core/acs_response.h"
#include "core/reader/json_reader.h"
#include "core/reader/xml_reader.h"

namespace aliyun {

AcsResponse::AcsResponse() {
}

AcsResponse::~AcsResponse() {
}

const string& AcsResponse::GetCode(void) const {
  return code_;
}
void AcsResponse::SetCode(const string& code) {
  code_ = code;
}

const string& AcsResponse::GetMessage(void) const {
  return message_;
}
void AcsResponse::SetMessage(const string& message) {
  message_ = message;
}

const string& AcsResponse::GetRequestId(void) const {
  return request_id_;
}
void AcsResponse::SetRequestId(const string& request_id) {
  request_id_ = request_id;
}

const string& AcsResponse::GetHostId(void) const{
  return host_id_;
}
void AcsResponse::SetHostId(const string& host_id) {
  host_id_ = host_id;
}

void AcsResponse::ParseBody(const unsigned char* body, size_t body_length, bool is_success, const string& format) {
  std::map<string, string> response_map;
  string base_key(is_success ? BaseKey() : "Error");
  if(format == "JSON") {
    JsonReader json_reader;
    json_reader.Parse((const char*)body, body_length, base_key, response_map);
  } else if(format == "XML") {
    XmlReader xml_reader;
    if(!xml_reader.Parse((const char*)body, body_length, base_key, response_map)) {
      SetCode("SDK.InvalidXMLParser");
      SetMessage("xml parse failed.");
      return ;
    }
  }
  if(is_success) {
    UnmarshallerString(request_id_, response_map, base_key + ".RequestId");
    UnmarshallerMap(response_map);
  } else {
    UnmarshallerString(request_id_, response_map, base_key + ".RequestId");
    UnmarshallerString(host_id_, response_map, base_key + ".HostId");
    UnmarshallerString(code_, response_map, base_key + ".Code");
    UnmarshallerString(message_, response_map, base_key + ".Message");
  }
}

const char* AcsResponse::BaseKey(void) {
  return "AcsResponse";
}

void AcsResponse::UnmarshallerMap(std::map<string, string>& map) {
}

void AcsResponse::UnmarshallerString(string& unmarshaller, std::map<string,string>& response_map, const string& path) {
  std::map<string,string>::const_iterator iter = response_map.find(path);
  if(iter != response_map.end()) {
    unmarshaller = iter->second;
  }
}

void AcsResponse::UnmarshallerBool(bool& unmarshaller, std::map<string,string>& response_map, const string& path) {
  std::map<string,string>::const_iterator iter = response_map.find(path);
  if(iter != response_map.end()) {
    unmarshaller = (iter->second == "true" ? true : false);
  }
}

void AcsResponse::UnmarshallerInt(int& unmarshaller, std::map<string,string>& response_map, const string& path) {
  std::map<string,string>::const_iterator iter = response_map.find(path);
  if(iter != response_map.end()) {
    unmarshaller = atoi(iter->second.c_str());
  }
}

void AcsResponse::UnmarshallerInt64(int64& unmarshaller, std::map<string,string>& response_map, const string& path) {
  std::map<string,string>::const_iterator iter = response_map.find(path);
  if(iter != response_map.end()) {
    #if defined(_MSC_VER)
      unmarshaller = _atoi64(iter->second.c_str());
    #elif defined(__GNUC__)
      unmarshaller = atoll(iter->second.c_str());
    #else
      #error "Unimplemented !!!"
    #endif
  }
}

void AcsResponse::UnmarshallerFloat(float& unmarshaller, std::map<string,string>& response_map, const string& path) {
  std::map<string,string>::const_iterator iter = response_map.find(path);
  if(iter != response_map.end()) {
    unmarshaller = atof(iter->second.c_str());
  }
}

} // namespace aliyun {

// end of file
